package com.binary.coder.gift.core.common.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.binary.coder.gift.core.common.bean.PageBean;
import com.binary.coder.gift.core.common.bean.PageParam;
import org.apache.ibatis.annotations.Param;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 注意这个类不要让 mp 扫描到！！
 */
public interface SuperMapper<T> extends BaseMapper<T> {


    /**
     * 转换成 Plus PageBean
     *
     * @param page
     * @return
     */
    default <M> IPage<M> toMapperPage(PageBean<M> page) {
        Page<M> bean = new Page<M>(page.getCurrent(), page.getSize(), page.getTotal());
        bean.setOptimizeCountSql(page.optimizeCountSql());
        if (page.ascs() != null)
            bean.addOrder(Arrays.asList(page.ascs()).stream().map(t->new OrderItem(t,true)).collect(Collectors.toList()));
        if (page.descs() != null)
            bean.addOrder(Arrays.asList(page.ascs()).stream().map(t->new OrderItem(t,false)).collect(Collectors.toList()));
        return bean;
    }

    /**
     * 创建 Plus PageBean
     *
     * @param page
     * @return
     */
    default IPage<T> createPlusPage(long page, long size) {
        Page<T> bean = new Page<T>(page, size);
        return bean;
    }

    default IPage<T> createPlusPage(PageParam pageParam) {
        Page<T> bean = new Page<T>(pageParam.getPageIndex(), pageParam.getPageSize());
        return bean;
    }

    /**
     * 创建controller PageBean
     *
     * @param page
     * @param size
     * @return
     */

    default PageBean<T> createBizPage(long page, long size) {
        return new PageBean<T>(page, size);
    }

    default PageBean<T> createBizPage(PageParam pageParam) {
        return new PageBean<T>(pageParam.getPageIndex(), pageParam.getPageSize());
    }

    /**
     * 转换成 Controller PageBean
     *
     * @param page
     * @return
     */
    default <M> PageBean<M> toBizPage(IPage<M> page) {
        PageBean<M> bean = new PageBean<M>(page.getCurrent(), page.getSize(), page.getTotal());
        bean.setOptimizeCountSql(page.optimizeCountSql());
        //bean.setAscs(page.ascs());
        //bean.setDescs(page.descs());
        bean.setRecords(page.getRecords());
        bean.condition();

        return bean;
    }

    /**
     * 转换成 Controller PageBean
     *
     * @param page
     * @return
     */
    default <M> PageBean<M> toBizPage(IPage<M> page, PageBean<M> bean) {
        bean.setCurrent(page.getCurrent());
        bean.setSize(page.getSize());
        bean.setTotal(page.getTotal());
        bean.setRecords(page.getRecords());
        return bean;
    }

    /**
     * <p>
     * 根据 entity 条件，查询全部记录（并翻页）
     * </p>
     *
     * @param page         分页查询条件（可以为 RowBounds.DEFAULT）
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    default PageBean<T> selectPage(PageBean<T> page, @Param("ew") Wrapper<T> queryWrapper) {
        IPage<T> pageBean = toMapperPage(page);
        pageBean = selectPage(pageBean, queryWrapper);
        toBizPage(pageBean, page);
        return page;
    }

    /**
     * <p>
     * 根据 Wrapper 条件，查询全部记录（并翻页）
     * </p>
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    default PageBean<Map<String, Object>> selectMapsPage(PageBean page, @Param("ew") Wrapper<T> queryWrapper) {
        IPage pageBean = toMapperPage(page);
        pageBean = selectMapsPage(pageBean, queryWrapper);
        toBizPage(pageBean, page);
        return page;
    }

    default QueryWrapper<T> createQuery() {
        return new QueryWrapper<T>();
    }


    /**
     * 只查询出一个对象
     *
     * @param queryWrapper
     * @return
     */
    default T selectOneBean(@Param("ew") Wrapper<T> queryWrapper) {
        Page<T> bean = new Page<T>(1l, 1l, 1l);
        bean.setOptimizeCountSql(false);
        this.selectPage(bean, queryWrapper);


        return getObject(bean.getRecords());
    }


    public static <E> E getObject(List<E> list) {
        if (CollectionUtils.isNotEmpty(list)) {
            int size = list.size();
            if (size > 1) {

            }
            return list.get(0);
        }
        return null;
    }


    /**
     * 只查询指定条数
     *
     * @param queryWrapper
     * @return
     */
    default T selectNextList(@Param("ew") Wrapper<T> queryWrapper, int size) {
        Page<T> bean = new Page<T>(1l, size, 1l);
        bean.setOptimizeCountSql(false);
        this.selectPage(bean, queryWrapper);

        return getObject(bean.getRecords());
    }


    default T lockById(Serializable id) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
        queryWrapper.eq("ID", id);
        queryWrapper.last("FOR UPDATE");//数据库层面锁住
        List<T> list = selectList(queryWrapper);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }


    /**
     * 是否存在
     *
     * @param id
     * @return
     */
    default boolean isExists(long id) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
        queryWrapper.eq("id", id);
        return this.selectCount(queryWrapper) > 0;

    }
}
